package edu.cque.jt.common.thread;

import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁,读的时候可以同时读,写的时候只能一个写,其他的都不能读,
 * 读是乐观锁,写时悲观锁
 * <p>
 * 可以保证线程安全的前提下,更实用与读多写少的情况
 */
public class RegistryTest {
    private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    static HashMap<String, String> registry = new HashMap<>();

    public static void doRegistry(String serviceId, String host) {
        readWriteLock.writeLock().lock();
        try {
            registry.put(serviceId, host);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    public static String doLookup(String serviceId) {
        readWriteLock.readLock().lock();
        String service = null;
        try {
            service = registry.get(serviceId);
            return serviceId;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }
        return service;
    }

    public static void main(String[] args) {
        String[] serviceIds = new String[100];
        String[] hosts = new String[100];
        for (int i = 0; i < serviceIds.length; i++) {
            serviceIds[i] = "serviceid" + i;
            hosts[i] = "hosts" + i;
        }
        new Thread() {
            @Override
            public void run() {
                super.run();
                for (int i = 0; i < serviceIds.length; i++) {
                    String serviceId = serviceIds[i];
                    doRegistry(serviceIds[i], hosts[i]);

                }
            }
        }.start();
        //2.构建线程对象,模拟服务注册和发现
        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(serviceIds[i] + ":" + doLookup(serviceIds[i]));
                }
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    registry.remove(serviceIds[i]);
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {
                    }
                }
            }
        }.start();


    }

}
